
impl Default for SemanticChecker {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_semantic_checker_creation() {
        let checker = SemanticChecker::new();
        assert!(checker.context.current_function.is_none());
        assert!(checker.context.current_struct.is_none());
        assert_eq!(checker.context.loop_depth, 0);
    }

    #[test]
    fn test_break_statement_outside_loop() {
        let mut checker = SemanticChecker::new();
        let symbol_table = SymbolTable::new();

        let break_stmt = crate::ast::stmt::BreakStmt {
            label: None,
            location: crate::error::Location::new(1, 1, 0),
        };

        let result = checker.check_break_statement(&break_stmt, &symbol_table);
        assert!(result.is_err());
    }

    #[test]
    fn test_continue_statement_outside_loop() {
        let mut checker = SemanticChecker::new();
        let symbol_table = SymbolTable::new();

        let continue_stmt = crate::ast::stmt::ContinueStmt {
            label: None,
            location: crate::error::Location::new(1, 1, 0),
        };

        let result = checker.check_continue_statement(&continue_stmt, &symbol_table);
        assert!(result.is_err());
    }

    #[test]
    fn test_return_statement_outside_function() {
        let mut checker = SemanticChecker::new();
        let symbol_table = SymbolTable::new();

        let return_stmt = crate::ast::stmt::ReturnStmt {
            value: None,
            location: crate::error::Location::new(1, 1, 0),
        };

        let result = checker.check_return_statement(&return_stmt, &symbol_table);
        assert!(result.is_err());
    }
}

impl SemanticChecker {
    /// Check an implementation declaration
    fn check_impl(&mut self, impl_: &ImplDecl, symbol_table: &mut SymbolTable) -> Result<()> {
        // Check that the type being implemented exists
        let type_exists = symbol_table.lookup_struct(&impl_.type_name).is_some()
            || symbol_table.lookup_type(&impl_.type_name).is_some();

        if !type_exists {
            return Err(CompilerError::semantic(
                impl_.location.line,
                impl_.location.column,
                format!(
                    "Cannot implement methods for undefined type '{}'",
                    impl_.type_name
                ),
            ));
        }

        // Check each method in the impl block
        for method in &impl_.methods {
            self.check_function(method, symbol_table)?;
        }

        Ok(())
    }
}
